package com.emagic.manage.utils;

import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.ClientCertRequest;
import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.alibaba.sdk.android.httpdns.HttpDns;
import com.alibaba.sdk.android.httpdns.HttpDnsService;
import com.emagic.manage.BuildConfig;
import com.emagic.manage.LifeApplication;

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Map;

public class WebViewUtil {

    private static final String TAG = WebViewUtil.class.getSimpleName();
    private static final String HTTP_DNS_ACCOUNT = "156280";
    private static HttpDnsService httpDns;

    static {
        httpDns = HttpDns.getService(LifeApplication.getInstance(), HTTP_DNS_ACCOUNT);
        ArrayList<String> hostList = new ArrayList<>();
        hostList.add("www.antaishenghuo.com");
        hostList.add("api.antaishenghuo.com");
        httpDns.setPreResolveHosts(hostList);
    }

    public static void setupWebView(WebView webView) {
        setupWebView(webView, null, null);
    }

    public static void setupWebView(WebView webView, WebViewClient webViewClient) {
        setupWebView(webView, webViewClient, null);
    }

    public static void setupWebView(WebView webView, WebChromeClient webChromeClient) {
        setupWebView(webView, null, webChromeClient);
    }

    @SuppressLint("SetJavaScriptEnabled")
    public static void setupWebView(WebView view, WebViewClient webViewClient, WebChromeClient webChromeClient) {

        final WebSettings settings = view.getSettings();
        settings.setDefaultTextEncodingName("utf-8");
        settings.setJavaScriptEnabled(true);
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        settings.setAllowFileAccess(true);
        settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
        settings.setSupportZoom(false);
        settings.setBuiltInZoomControls(false);
        settings.setUseWideViewPort(true);
        settings.setLoadWithOverviewMode(true);
        settings.setAppCacheEnabled(true);
        settings.setDatabaseEnabled(true);
        settings.setDomStorageEnabled(true);
        settings.setGeolocationEnabled(true);
        settings.setCacheMode(WebSettings.LOAD_NO_CACHE);

        view.setWebViewClient(new WebViewClientWrapper(webViewClient));
        view.setWebChromeClient(webChromeClient);
    }


    private static class WebViewClientWrapper extends WebViewClient {

        private WebViewClient childWebViewClient;

        public WebViewClientWrapper(WebViewClient childWebViewClient) {
            this.childWebViewClient = childWebViewClient;
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if (childWebViewClient != null) {
                return childWebViewClient.shouldOverrideUrlLoading(view, url);
            }
            return super.shouldOverrideUrlLoading(view, url);
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            if (childWebViewClient != null) {
                childWebViewClient.onPageStarted(view, url, favicon);
            } else {
                super.onPageStarted(view, url, favicon);
            }
        }

        @Override
        public void onPageFinished(WebView view, String url) {

            if (childWebViewClient != null) {
                childWebViewClient.onPageFinished(view, url);
            } else {
                super.onPageFinished(view, url);
            }

        }

        @Override
        public void onLoadResource(WebView view, String url) {

            if (childWebViewClient != null) {
                childWebViewClient.onLoadResource(view, url);
            } else {
                super.onLoadResource(view, url);
            }
        }

        @SuppressLint("NewApi")
        @Override
        public void onPageCommitVisible(WebView view, String url) {
            if (childWebViewClient != null) {
                childWebViewClient.onPageCommitVisible(view, url);
            } else {
                super.onPageCommitVisible(view, url);
            }
        }


        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {

            if (BuildConfig.DEBUG) {
                return super.shouldInterceptRequest(view, url);
            }
            // API < 21 只能拦截URL参数
            if (!TextUtils.isEmpty(url) && Uri.parse(url).getScheme() != null) {
                String scheme = Uri.parse(url).getScheme().trim();
                Log.d(TAG, "url: " + url);
                // 假设我们对所有css文件的网络请求进行httpdns解析
                if ((scheme.equalsIgnoreCase("http") || scheme.equalsIgnoreCase("https")) && url.contains(".css")) {
                    try {
                        URL oldUrl = new URL(url);
                        URLConnection connection = oldUrl.openConnection();
                        // 异步获取域名解析结果
                        String ip = httpDns.getIpByHostAsync(oldUrl.getHost());
                        if (ip != null) {
                            // 通过HTTPDNS获取IP成功，进行URL替换和HOST头设置
                            Log.d(TAG, "Get IP: " + ip + " for host: " + oldUrl.getHost() + " from HTTPDNS successfully!");
                            String newUrl = url.replaceFirst(oldUrl.getHost(), ip);
                            connection = new URL(newUrl).openConnection();
                            // 设置HTTP请求头Host域
                            connection.setRequestProperty("Host", oldUrl.getHost());
                        }
                        Log.d(TAG, "ContentType: " + connection.getContentType());

                        WebResourceResponse wr = null;
                        if (childWebViewClient != null) {
                            wr = childWebViewClient.shouldInterceptRequest(view, url);
                        }

                        if (wr == null) {
                            wr = new WebResourceResponse(connection.getContentType(), "UTF-8", connection.getInputStream());
                        } else {
                            wr.setMimeType(connection.getContentType());
                            wr.setEncoding("UTF-8");
                            wr.setData(connection.getInputStream());
                        }

                        return wr;
                    } catch (IOException e) {
                        Log.e(TAG, "shouldInterceptRequest: " + e.getMessage(), e);
                    }
                }
            }
            return childWebViewClient != null ? childWebViewClient.shouldInterceptRequest(view, url) : super.shouldInterceptRequest(view, url);

        }

        @SuppressWarnings("NewApi")
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {

            if (BuildConfig.DEBUG) {
                return super.shouldInterceptRequest(view, request);
            }

            // 新的API可以拦截POST请求
            if (request != null && request.getUrl() != null && request.getMethod().equalsIgnoreCase("get")) {
                String scheme = request.getUrl().getScheme().trim();
                Map<String, String> headerFields = request.getRequestHeaders();
                String url = request.getUrl().toString();
                Log.d(TAG, "request.getUrl().toString(): " + url);
                // 假设我们对所有css文件的网络请求进行httpdns解析
                if ((scheme.equalsIgnoreCase("http") || scheme.equalsIgnoreCase("https")) && request.getUrl().toString().contains(".css")) {
                    try {
                        URL oldUrl = new URL(url);
                        URLConnection connection = oldUrl.openConnection();
                        // 异步获取域名解析结果
                        String ip = httpDns.getIpByHostAsync(oldUrl.getHost());
                        if (ip != null) {
                            // 通过HTTPDNS获取IP成功，进行URL替换和HOST头设置
                            Log.d(TAG, "Get IP: " + ip + " for host: " + oldUrl.getHost() + " from HTTPDNS successfully!");
                            String newUrl = url.replaceFirst(oldUrl.getHost(), ip);
                            connection = new URL(newUrl).openConnection();

                            // 设置HTTP请求头Host域
                            connection.setRequestProperty("Host", oldUrl.getHost());
                        }
                        // copy请求header参数
                        for (String header : headerFields.keySet()) {
                            connection.setRequestProperty(header, headerFields.get(header));
                        }
                        // 注*：对于POST请求的Body数据，WebResourceRequest接口中并没有提供，这里无法处理
                        Log.d(TAG, "ContentType: " + connection.getContentType());

                        WebResourceResponse wr = null;
                        if (childWebViewClient != null) {
                            wr = childWebViewClient.shouldInterceptRequest(view, request);
                        }

                        if (wr == null) {
                            wr = new WebResourceResponse(connection.getContentType(), "UTF-8", connection.getInputStream());
                        } else {
                            wr.setMimeType(connection.getContentType());
                            wr.setEncoding("UTF-8");
                            wr.setData(connection.getInputStream());
                        }

                        return wr;
                    } catch (IOException e) {
                        Log.e(TAG, "shouldInterceptRequest: " + e.getMessage(), e);
                    }
                }
            }

            return childWebViewClient != null ? childWebViewClient.shouldInterceptRequest(view, request) : super.shouldInterceptRequest(view, request);

        }

        @Override
        public void onTooManyRedirects(WebView view, Message cancelMsg, Message continueMsg) {

            if (childWebViewClient != null) {
                childWebViewClient.onTooManyRedirects(view, cancelMsg, continueMsg);
            } else {
                super.onTooManyRedirects(view, cancelMsg, continueMsg);
            }
        }

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {

            if (childWebViewClient != null) {
                childWebViewClient.onReceivedError(view, errorCode, description, failingUrl);
            } else {
                super.onReceivedError(view, errorCode, description, failingUrl);
            }
        }

        @SuppressLint("NewApi")
        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {

            if (childWebViewClient != null) {
                childWebViewClient.onReceivedError(view, request, error);
            } else {
                super.onReceivedError(view, request, error);
            }
        }

        @SuppressLint("NewApi")
        @Override
        public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {

            if (childWebViewClient != null) {
                childWebViewClient.onReceivedHttpError(view, request, errorResponse);
            } else {
                super.onReceivedHttpError(view, request, errorResponse);
            }
        }

        @Override
        public void onFormResubmission(WebView view, Message dontResend, Message resend) {

            if (childWebViewClient != null) {
                childWebViewClient.onFormResubmission(view, dontResend, resend);
            } else {
                super.onFormResubmission(view, dontResend, resend);
            }
        }

        @Override
        public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {

            if (childWebViewClient != null) {
                childWebViewClient.doUpdateVisitedHistory(view, url, isReload);
            } else {
                super.doUpdateVisitedHistory(view, url, isReload);
            }
        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {

            if (childWebViewClient != null) {
                childWebViewClient.onReceivedSslError(view, handler, error);
            } else {
                super.onReceivedSslError(view, handler, error);
            }
        }

        @SuppressLint("NewApi")
        @Override
        public void onReceivedClientCertRequest(WebView view, ClientCertRequest request) {

            if (childWebViewClient != null) {
                childWebViewClient.onReceivedClientCertRequest(view, request);
            } else {
                super.onReceivedClientCertRequest(view, request);
            }
        }

        @Override
        public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {

            if (childWebViewClient != null) {
                childWebViewClient.onReceivedHttpAuthRequest(view, handler, host, realm);
            } else {
                super.onReceivedHttpAuthRequest(view, handler, host, realm);
            }
        }

        @Override
        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {

            if (childWebViewClient != null) {
                return childWebViewClient.shouldOverrideKeyEvent(view, event);
            } else {
                return super.shouldOverrideKeyEvent(view, event);
            }
        }

        @Override
        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {

            if (childWebViewClient != null) {
                childWebViewClient.onUnhandledKeyEvent(view, event);
            } else {
                super.onUnhandledKeyEvent(view, event);
            }
        }


        @Override
        public void onScaleChanged(WebView view, float oldScale, float newScale) {

            if (childWebViewClient != null) {
                childWebViewClient.onScaleChanged(view, oldScale, newScale);
            } else {
                super.onScaleChanged(view, oldScale, newScale);
            }
        }

        @Override
        public void onReceivedLoginRequest(WebView view, String realm, String account, String args) {

            if (childWebViewClient != null) {
                childWebViewClient.onReceivedLoginRequest(view, realm, account, args);
            } else {
                super.onReceivedLoginRequest(view, realm, account, args);
            }
        }
    }
}
